
public class WalkingBass implements Runnable {
	
	public static Object[] noteArray = new Object[2];
	public int octave = 4;
	public static Integer[][] notes=null;
	public void run()
	{


//		System.out.println("COUNT = "+Main.count);
		Main.count++;
		
		boolean directionUp=false;
		if (notes==null&&Main.walkingBassArrayPointer>0)
		{
			if (Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]+Main.score.key<56)
			{directionUp=true;}
			else if (Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]+Main.score.key>56)
			{directionUp=false;}
			else if (Math.random()>.5)
			{directionUp=true;}
			else
			{directionUp=false;}
		}
		else if (notes!=null)
		{
			if (notes[0][notes[0].length-1]+Main.score.key<48+9)
			{directionUp=true;}
			else if (notes[0][notes[0].length-1]>59)
			{directionUp=false;}
			else if (Math.random()>.5)
			{directionUp=true;}
			else
			{directionUp=false;}
		}
		else
		{
			int startPch = findChord(Main.score.chordPointer)[0]+12*4+Main.score.key;
//			System.out.println("Start Pitch = "+startPch);
			if (startPch<59)
			{
				directionUp=true;
			}
			else
			{
				directionUp=false;
			}
		}
//		System.out.println("chordCount = "+Main.score.chordPointer);
//		System.out.println("CHORD POINTER pitch = "+findChord(Main.score.chordPointer)[0]);
		
		int distance = Main.score.changes[0][(Main.score.chordPointer+1)%Main.score.changes[0].length]-Main.score.changes[0][Main.score.chordPointer%Main.score.changes[0].length];
		if (distance<0)
		{
			distance = distance+12;
		}
//		System.out.println("Distance = "+distance);
		int wbindex = findWBPattern(distance);
//		if(wbindex!=99&&Math.random()>.5)
		if(true)
		{
			if (findChord(Main.score.chordPointer)[2]>=192)
			{
				// System.out.println("found match");
				int numOptions=0;
				notes=new Integer[2][4];
				if (!directionUp)
				{
					int[] options = null;
					int[] tempOptions = null;
					for (int i=1;i<Constants.wblines[wbindex].length;i=i+4)
					{
						if (Constants.wblines[wbindex][i]==12)
						{
							numOptions++;
							if (options!=null)
							{
								tempOptions = options;
								options = new int[options.length+1];
								System.arraycopy(tempOptions, 0, options, 0, tempOptions.length);
								options[options.length-1]=i;
							}
							else
							{
								options = new int[1];
								options[0]=i;
							}
						}
					}
					if (numOptions==0) // no matches that start high, use generative method
					{
						wbindex=99;
					}
					else
					{
						int selectOption = options[(int)(Math.random()*numOptions)];
//						System.out.println("********************************** wbindex = "+wbindex+" **********************");
//						System.out.println("********************************** selectOption = "+selectOption+" ********************");
						for (int i=0;i<4;i++)
						{
							if (Main.walkingBassArrayPointer>0)
							{

								if (i==0)
								{
//									int pitchclass = (findChord(Main.score.chordPointer)[0])%12;
//									int target = Main.walkingBassArray[0][Main.walkingBassArrayPointer-1];
//									System.out.println("pitch class: "+pitchclass+" target = "+target);
									notes[0][i]=Generation.nearestAbs((findChord(Main.score.chordPointer)[0]+Constants.wblines[wbindex][selectOption+i])%12,Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
								}
								else
								{
									notes[0][i]=notes[0][0]-12+Constants.wblines[wbindex][selectOption+i]%12;									
								}
								notes[1][i]=48;
							}
							else
							{
								notes[0][i]=findChord(Main.score.chordPointer)[0]+12*4+Constants.wblines[wbindex][selectOption+i]-12;
								notes[1][i]=48;
							}
//							if (notes[0][i]<48)
//							{
//								notes[0][i]=notes[0][i]+12;
//							}
						}
//						System.out.println("********************************** direction down ********************");
					}
				}
				else
				{
					int[] options = null;
					int[] tempOptions = null;
					for (int i=1;i<Constants.wblines[wbindex].length;i=i+4)
					{
						if (Constants.wblines[wbindex][i]==0)
						{
							numOptions++;
							if (options!=null)
							{
								tempOptions = options;
								options = new int[options.length+1];
								System.arraycopy(tempOptions, 0, options, 0, tempOptions.length);
								options[options.length-1]=i;
								
							}
							else
							{
								options = new int[1];
								options[0]=i;
							}
						}
					}
					if (numOptions==0) // no matches that start high, use generative method
					{
						wbindex=99;
					}
					else
					{
						int selectOption = options[(int)(Math.random()*numOptions)];
//						System.out.println("********************************** wbindex = "+wbindex+" **********************");
//						System.out.println("********************************** selectOption = "+selectOption+" ********************");
						for (int i=0;i<4;i++)
						{
							if (Main.walkingBassArrayPointer>0)
							{

								if (i==0)
								{
//									int pitchclass = (findChord(Main.score.chordPointer)[0])%12;
//									int target = Main.walkingBassArray[0][Main.walkingBassArrayPointer-1];
//									System.out.println("pitch class: "+pitchclass+" target = "+target);
									notes[0][i]=Generation.nearestAbs((findChord(Main.score.chordPointer)[0]+Constants.wblines[wbindex][selectOption+i])%12,Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
								}
								else
								{
									notes[0][i]=notes[0][0]+Constants.wblines[wbindex][selectOption+i]%12;								}
								notes[1][i]=48;
							}
							else
							{
								notes[0][i]=findChord(Main.score.chordPointer)[0]+12*4+Constants.wblines[wbindex][selectOption+i];
								notes[1][i]=48;
							}
//							if (notes[0][i]<48)
//							{
//								notes[0][i]=notes[0][i]+12;
//							}
						}
						
//						System.out.println("********************************** direction up ********************");
					}
				}
				if (numOptions>0)
				{
					for (int j=0;j<notes[0].length;j++)
					{
						Main.walkingBassArray[0][Main.walkingBassArrayPointer]=fixOctave(notes[0][j]);
						Main.walkingBassArray[1][Main.walkingBassArrayPointer]=notes[1][j];
						Main.walkingBassArrayPointer++;
					}
				}
			}
			else
			{
// ----------------------------------- wb / half a bar ---------------------------------------------------------
				// System.out.println("found match -half");
				int numOptions=0;
				notes=new Integer[2][4];
				if (!directionUp)
				{
					int[] options = null;
					int[] tempOptions = null;
					for (int i=1;i<Constants.wblines_half[wbindex].length;i=i+2)
					{
						if (Constants.wblines_half[wbindex][i]==12) // patterns that start on 12 go down
						{
							numOptions++;
							if (options!=null)
							{
								tempOptions = options;
								options = new int[options.length+1];
								System.arraycopy(tempOptions, 0, options, 0, tempOptions.length);
								options[options.length-1]=i;
							}
							else
							{
								options = new int[1];
								options[0]=i;
							}
						}
					}
					if (numOptions==0) // no matches that start high, use generative method
					{
						wbindex=99;
					}
					else
					{
						int selectOption = options[(int)(Math.random()*numOptions)];
//						System.out.println("********************************** wbindex = "+wbindex+" **********************");
//						System.out.println("********************************** selectOption = "+selectOption+" ********************");
						for (int i=0;i<2;i++)
						{
							if (Main.walkingBassArrayPointer>0)
							{

								if (i==0)
								{
//									int pitchclass = (findChord(Main.score.chordPointer)[0])%12;
//									int target = Main.walkingBassArray[0][Main.walkingBassArrayPointer-1];
//									System.out.println("pitch class: "+pitchclass+" target = "+target);
									notes[0][i]=Generation.nearestAbs((findChord(Main.score.chordPointer)[0]+Constants.wblines_half[wbindex][selectOption+i])%12,Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
								}
								else
								{
//									System.out.println("down -- note[0][0] = "+notes[0][0]+" alterPch = "+alterPch(Constants.wblines_half[wbindex][selectOption+i])%12);
//									System.out.println("down -- note[0][1] = "+(notes[0][0]-12+alterPch(Constants.wblines_half[wbindex][selectOption+i])%12));
									notes[0][i]=notes[0][0]-12+Constants.wblines_half[wbindex][selectOption+i]%12;								
								}
								notes[1][i]=48;
							}
							else
							{
								notes[0][i]=findChord(Main.score.chordPointer)[0]+12*4+Constants.wblines_half[wbindex][selectOption+i]-12;
								notes[1][i]=48;
							}
						}
						for (int j=0;j<2;j++)
						{
							Main.walkingBassArray[0][Main.walkingBassArrayPointer]=fixOctave(notes[0][j]);
							Main.walkingBassArray[1][Main.walkingBassArrayPointer]=notes[1][j];
							Main.walkingBassArrayPointer++;
						}
						Main.score.chordPointer++;
//						System.out.println("********************************** wbindex 1/2 = "+wbindex+" **********************");
//						System.out.println("********************************** direction down ********************");
					}
				}
				else
				{
					int[] options = null;
					int[] tempOptions = null;
					for (int i=1;i<Constants.wblines_half[wbindex].length;i=i+2)
					{
						if (Constants.wblines_half[wbindex][i]==0)
						{
							numOptions++;
							if (options!=null)
							{
								tempOptions = options;
								options = new int[options.length+1];
								System.arraycopy(tempOptions, 0, options, 0, tempOptions.length);
								options[options.length-1]=i;
								
							}
							else
							{
								options = new int[1];
								options[0]=i;
							}
						}
					}
					if (numOptions==0) // no matches that start low, use generative method
					{
						wbindex=99;
					}
					else
					{
						int selectOption = options[(int)(Math.random()*numOptions)];
//						System.out.println("********************************** wbindex 1/2 = "+wbindex+" **********************");
//						System.out.println("********************************** selectOption = "+selectOption+" ********************");
						for (int i=0;i<2;i++)
						{
							if (Main.walkingBassArrayPointer>0)
							{

								if (i==0)
								{
//									int pitchclass = (findChord(Main.score.chordPointer)[0])%12;
//									int target = Main.walkingBassArray[0][Main.walkingBassArrayPointer-1];
//									System.out.println("pitch class: "+pitchclass+" target = "+target);
									notes[0][i]=Generation.nearestAbs((findChord(Main.score.chordPointer)[0]+Constants.wblines_half[wbindex][selectOption+i])%12,Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
								}
								else
								{
									notes[0][i]=notes[0][0]+Constants.wblines_half[wbindex][selectOption+i]%12;
								}
								notes[1][i]=48;
							}
							else
							{
								notes[0][i]=findChord(Main.score.chordPointer)[0]+12*4+Constants.wblines_half[wbindex][selectOption+i];
								notes[1][i]=48;
							}
						}
						for (int j=0;j<2;j++)
						{
							Main.walkingBassArray[0][Main.walkingBassArrayPointer]=fixOctave(notes[0][j]);
							Main.walkingBassArray[1][Main.walkingBassArrayPointer]=notes[1][j];
							Main.walkingBassArrayPointer++;
						}
						Main.score.chordPointer++;
//						System.out.println("********************************** direction up ********************");
					}
				}
				distance = Main.score.changes[0][(Main.score.chordPointer+1)%Main.score.changes[0].length]-Main.score.changes[0][Main.score.chordPointer%Main.score.changes[0].length];
				if (distance<0)
				{
					distance = distance+12;
				}
				wbindex = findWBPattern(distance);
				numOptions=0;
				int[] options = null;
				int[] tempOptions = null;
				for (int i=1;i<Constants.wblines_half[wbindex].length;i=i+2)
				{
					if (!directionUp)
					{
						if (Constants.wblines_half[wbindex][i]==12) // patterns that start on 12 go down
						{
							numOptions++;
							if (options!=null)
							{
								tempOptions = options;
								options = new int[options.length+1];
								System.arraycopy(tempOptions, 0, options, 0, tempOptions.length);
								options[options.length-1]=i;
							}
							else
							{
								options = new int[1];
								options[0]=i;
							}
						}
					}
					else {
						if (Constants.wblines_half[wbindex][i]==0) // patterns that start on 12 go down
						{
							numOptions++;
							if (options!=null)
							{
								tempOptions = options;
								options = new int[options.length+1];
								System.arraycopy(tempOptions, 0, options, 0, tempOptions.length);
								options[options.length-1]=i;
							}
							else
							{
								options = new int[1];
								options[0]=i;
							}
						}
					}
				}
				int optionIndex = (int)(Math.random()*numOptions);
				// System.out.println("Option Index = "+optionIndex);
				int selectOption = options[optionIndex];
//				System.out.println("********************************** wbindex 2/2 = "+wbindex+" **********************");
//				System.out.println("********************************** selectOption = "+selectOption+" ********************");
				for (int i=2;i<4;i++)
				{
					if (Main.walkingBassArrayPointer>0)
					{

						if (i==2)
						{
//							int pitchclass = (findChord(Main.score.chordPointer)[0])%12;
//							int target = Main.walkingBassArray[0][Main.walkingBassArrayPointer-1];
//							System.out.println("pitch class: "+pitchclass+" target = "+target);
							// System.out.println("pitch class = "+(findChord(Main.score.chordPointer)[0])%12);
							// System.out.println("last chord = "+Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
							notes[0][i]=Generation.nearestAbs((findChord(Main.score.chordPointer)[0])%12,Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
						}
						else
						{
							if (!directionUp)
							{
								// System.out.println("direction down notes[0][2] "+notes[0][2]);
								notes[0][i]=notes[0][2]-12+Constants.wblines_half[wbindex][selectOption+i-2]%12;
							}
							else
							{
								// System.out.println("direction up notes[0][2] "+notes[0][2]);
								// System.out.println("alterPch = "+Constants.wblines_half[wbindex][selectOption+i-2]%12);
								// System.out.println("constants.wblines_half = "+(Constants.wblines_half[wbindex][selectOption+i-2])%12);
								notes[0][i]=notes[0][2]+Constants.wblines_half[wbindex][selectOption+i-2]%12;
							}
						}
						notes[1][i]=48;
					}
					else
					{
						notes[0][i]=findChord(Main.score.chordPointer)[0]+12*4+Constants.wblines_half[wbindex][selectOption+i-2]-12;
						notes[1][i]=48;
					}
				}
				if (numOptions>0)
				{
					for (int j=2;j<4;j++)
					{
						Main.walkingBassArray[0][Main.walkingBassArrayPointer]=fixOctave(notes[0][j]);
						Main.walkingBassArray[1][Main.walkingBassArrayPointer]=notes[1][j];
						Main.walkingBassArrayPointer++;
					}
				}
			}
		}
//		else
//		{
//			wbindex=99;
//		}
		if(wbindex==99)
		{
			// System.out.println("********* gen ");
			if (directionUp)
			{
				// System.out.println("********************************** direction up ********************");
			}
			else
			{
				// System.out.println("********************************** direction down ********************");
			}
			switch((int)(Math.random()*2))
			{
			case(0):
				if (Main.walkingBassArrayPointer>0)
				{
					// System.out.println("START pitch class = "+findChord(Main.score.chordPointer)[0]);
					// System.out.println("START last note / target = "+Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
					// System.out.println("START TONE = "+Generation.nearestAbs(findChord(Main.score.chordPointer)[0], Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]));
					notes = new Integer[][]{Generation.genScale(Generation.nearestAbs(findChord(Main.score.chordPointer)[0], Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]), 4, findChord(Main.score.chordPointer)[0],convertDegreeToScale(findChord(Main.score.chordPointer)[0]), directionUp ),Generation.genRhythmStatic(4,48)};
				}
				else
				{
					notes = new Integer[][]{Generation.genScale(findChord(Main.score.chordPointer)[0]+12*4, 4, findChord(Main.score.chordPointer)[0],convertDegreeToScale(findChord(Main.score.chordPointer)[0]), directionUp ),Generation.genRhythmStatic(4,48)};					
				}
				break;
			case(1):
				if (Main.walkingBassArrayPointer>0)
				{
					// System.out.println("START pitch class = "+findChord(Main.score.chordPointer)[0]);
					// System.out.println("START last note / target = "+Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]);
					// System.out.println("START TONE = "+Generation.nearestAbs(findChord(Main.score.chordPointer)[0], Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]));
					notes = new Integer[][]{Generation.genArp(Generation.nearestAbs(findChord(Main.score.chordPointer)[0], Main.walkingBassArray[0][Main.walkingBassArrayPointer-1]), 4, findChord(Main.score.chordPointer)[0],findChord(Main.score.chordPointer)[1], directionUp ),Generation.genRhythmStatic(4,48)};
				}
				else
				{
					notes = new Integer[][]{Generation.genArp(findChord(Main.score.chordPointer)[0]+12*4, 4, findChord(Main.score.chordPointer)[0],findChord(Main.score.chordPointer)[1], directionUp ),Generation.genRhythmStatic(4,48)};					
				}
				break;
			case(2):
				break;
			}
			Integer apTone = Generation.approachTone(findChord(((Main.score.chordPointer+1)%Main.score.changes[2].length))[0],notes[0][2]);
			// System.out.println("APPROACH TONE = "+apTone+" Target = "+findChord(((Main.score.chordPointer+1)%Main.score.changes[2].length))[0]);
			notes[0][3]=apTone;
			
			for (int j=0;j<notes[0].length;j++)
			{
				if (notes[0][j]<48)
				{
					notes[0][j]=notes[0][j]+12;
				}
				Main.walkingBassArray[0][Main.walkingBassArrayPointer]=notes[0][j];
				Main.walkingBassArray[1][Main.walkingBassArrayPointer]=notes[1][j];
				Main.walkingBassArrayPointer++;
			}
		}
		
		notes[0]=alterSeq(notes[0]);
		for (int i=0;i<notes[0].length;i++)
		{
			Main.walkingBassArray[0][Main.walkingBassArrayPointer-1-i]=notes[0][notes[0].length-1-i];
		}
		int lastOnset = -480;		
		for (int i=0;i<notes[0].length;i++)
		{
			noteOut(notes[0][i],100,notes[1][i]*10+lastOnset);
			lastOnset+=notes[1][i]*10;
		}

		
	}
	
	public static Integer[] alterSeq(Integer[] notes)
	{
		if (Transformations.noteInScale(Main.score.changes[0][(Main.score.chordPointer)%Main.score.changes[0].length],Transformations.makeScaleMajorMinor(0,!Main.score.isMinor)))// only alter the chord if root is diatonic...
		{
			for (int i=1;i<notes.length;i++)
			{
				int[] scale = Transformations.makeScaleMajorMinor(0,!Main.score.isMinor); //create the diatonic scale
				for (int j=0;j<scale.length;j++) // modify the scale based on quality of the chord
				{
					if ((findChord(Main.score.chordPointer%Main.score.changes[0].length)[1]&8)>0&&(scale[j]+findChord(Main.score.chordPointer%Main.score.changes[0].length)[0])%12==4) // test if the note is the third of the chord and it is a minor triad
					{
						scale[j]--;
					}
					if ((findChord(Main.score.chordPointer%Main.score.changes[0].length)[1]&128)==0&&(scale[j]+(findChord(Main.score.chordPointer%Main.score.changes[0].length)[0]))%12==7) // test if the note is the fifth of the chord and it is a diminished triad
					{
						scale[j]--;								
					}		
					if ((findChord(Main.score.chordPointer%Main.score.changes[0].length)[1]&1024)==0&&(findChord(Main.score.chordPointer%Main.score.changes[0].length)[1]&512)==0&&(scale[j]+(findChord(Main.score.chordPointer%Main.score.changes[0].length)[0]))%12==10) // test if it is not a dominant 7 and not fully diminished -- then use major seventh
					{
						scale[j]++;								
					}
					if ((findChord(Main.score.chordPointer%Main.score.changes[0].length)[1]&512)>0&&(scale[j]+(findChord(Main.score.chordPointer%Main.score.changes[0].length)[0]))%12==10) // test if the note is the seventh of the chord and it is a diminished triad
					{
						scale[j]--;								
					}
		
				}
				
				
				if (i==1||i==2)
				{			
					
					if (!Transformations.noteInScale(notes[i],scale)&&notes[i-1]!=notes[i]-1&&notes[i+1]!=notes[i]-1)
					{
						// System.out.println("******* ----- note index "+i+" pitch "+notes[i]+" is in scale? "+Transformations.noteInScale(i,Transformations.makeScaleMajorMinor(0,!Main.score.isMinor)));
						int noteIndex=(notes[i]-Main.score.changes[0][Main.score.chordPointer%Main.score.changes[0].length%Main.score.changes[0].length])%12;
						if (noteIndex==2||noteIndex==4||noteIndex==5||noteIndex==7||noteIndex==9||noteIndex==11)
						{
							notes[i]--;
						}
						if (noteIndex==1||noteIndex==3||noteIndex==6||noteIndex==8||noteIndex==10)
						{
							notes[i]++;
						}
					}
				}
				
				if (i==3)
				{
	//				if (!Transformations.noteInScale(notes[i],scale)&&notes[i-1]!=notes[i]-1)
	//				{
	//					System.out.println("note index "+i+" pitch "+notes[i]+" is in scale? "+Transformations.noteInScale(i,Transformations.makeScaleMajorMinor(Main.score.key,!Main.score.isMinor)));
	//					int noteIndex=(notes[i]-Main.score.changes[0][Main.score.chordPointer%Main.score.changes[0].length%Main.score.changes[0].length])%12;
	//					if (noteIndex==2||noteIndex==4||noteIndex==5||noteIndex==7||noteIndex==9||noteIndex==11)
	//					{
	//						notes[i]--;
	//					}
	//					if (noteIndex==1||noteIndex==3||noteIndex==6||noteIndex==8||noteIndex==10)
	//					{
	//						notes[i]++;
	//					}
	//				}
				}
			}
		}
		return notes;
	}
	public static int findWBPattern(int chordRoot)
	{
		int match = 99;
		if (findChord(Main.score.chordPointer%Main.score.changes[0].length)[2]>=192)
		{
			for (int i=0;i<Constants.wblines.length;i++)
			{
				if (chordRoot == Constants.wblines[i][0])
				{
					match = i;
				}
			}
		}
		else
		{
			for (int i=0;i<Constants.wblines_half.length;i++)
			{
				if (chordRoot == Constants.wblines_half[i][0])
				{
					match = i;
				}
			}
		}
		return match;
	}

	public void findOctave(int lastPch, int nextPchClass){
//		find the octave of the next pitch, closest to the last
		int distance = 127;

		for (int i=0;i<12;i++)
		{
			if (Math.abs(lastPch-(nextPchClass+12*i))<distance)
			{
				distance = Math.abs(lastPch-(nextPchClass+12*i));
				octave = i;
			}
		}
		// System.out.println("findOctave lastPch = "+lastPch+" nextPchClass = "+nextPchClass+" octave = "+octave);
	}
	public void findOctaveNotes(){
		if (notes[0][notes[0].length-1]<58)
		{
			octave = 4;						
		}
		else
		{
			octave = 5;
		}
	}
//	find a chord in the score Main.score.changes at a specific symbolic time
	public static int[] findChord(int chordPointer)
	{
		int[] chord={Main.score.changes[0][chordPointer%Main.score.changes[0].length],Main.score.changes[1][chordPointer%Main.score.changes[0].length],Main.score.changes[2][chordPointer%Main.score.changes[0].length]};
		return chord;
	}
//	find a chord index at a specific symbolic time
	public static int findChordIndex(int time)
	{
		int timeCount=0;
		int i=0; 
//		System.out.println("time = "+time+" timeCount = "+timeCount+" i = "+i+" change.length = "+Main.score.changes.length);
		while (i<Main.score.changes[2].length&&timeCount<time)
		{
			if (timeCount<=time)
			{
				i++;
			}
			timeCount=timeCount+Main.score.changes[2][i];

		}
		return i;
	}
//	convert an integer into an int[] where 1s mean the note is on and 0s the note is off ... 32 notes above bass note.
	public int[] toChord(int chordInt)
	{
		String chord = Integer.toBinaryString(chordInt);
		char[] chordCharArray = chord.toCharArray();
		int[] chordArray = new int[chordCharArray.length];
		int j=0;
		for (int i=0;i<chordCharArray.length;i++)
		{
			chordArray[i]=(int) (chordCharArray[chordCharArray.length-i-1]) - 48;
//			System.out.println("chord "+i+" = "+chordArray[i]);
			if (chordArray[i]==1)
			{
				j++;
			}
		}
		int[] notesArray = new int[j];
		j=0;
		for (int i=0;i<chordCharArray.length;i++)
		{
			if (chordArray[i]==1)
			{
				notesArray[j]=i;
				j++;
			}
		}
		return notesArray;
	}
	
//	concatenate Generalizable Objects
	@SuppressWarnings("unchecked")
	static <T> T[] concat(T[] a, T[] b) {
	    final int alen = a.length;
	    final int blen = b.length;
	    final T[] result = (T[]) java.lang.reflect.Array.
	            newInstance(a.getClass().getComponentType(), alen + blen);
	    System.arraycopy(a, 0, result, 0, alen);
	    System.arraycopy(b, 0, result, alen, blen);
	    return result;
	}
	
	public static int convertDegreeToScale(int index)
	{
		int[] conversionChart = { 	0,2,4,5,7,9,11	};
		int match=-1;
		for (int i=0;i<conversionChart.length;i++)
		{
			if (index == conversionChart[i])
			{
				match = i;
			}
		}
		if (match==-1)
		{
			System.out.println("!!!!!!!! illegal index for conversion -------> "+index);
		}
		return match;
		
	}
	public static int fixOctave(int note)
	{
		if (note<48)
		{
			note=note%12;
			note=note+48;
		}
		return note;
	}
	public static void noteOut(int note, int vel,int onset){
		vel = 105;
		Main.score.WBDone=true;
		System.out.println("generated WB note:" + (note + Main.score.key)
				+ " " + onset);
		
		note = note+Main.score.key;
//		System.out.println("to be generated WB note:" + note + " " + vel + " " + wait);


		if (note<48)
		{
			note=note%12;
			note=note+48;
		}
		
		if (note==48)
		{
			note=60;
		}
		if (note>=62)
		{
			note=note%12;
			note=note+48;
		}
		Main.lastPchOut = note;
		// add note to notes out


		boolean bound = false;
		if (Main.noteOut[2]==null) {
			Main.noteOut = new int[3][1];
			Main.noteOut[0][0]=note;
			Main.noteOut[1][0]=vel;
			Main.noteOut[2][0]=onset;
		}
		else {		
			int index=Main.noteOut[2].length-1;
			while (!bound&&index>=0)
			{
				if  (onset>=Main.noteOut[2][index]) {
					bound = true;
				}
				else {
					index--;
				}
			}
			int[][] tempOut = new int[3][Main.noteOut[2].length+1];
			int index2=0;
			while (index2<=index)
			{
				tempOut[0][index2]=Main.noteOut[0][index2];
				tempOut[1][index2]=Main.noteOut[1][index2];
				tempOut[2][index2]=Main.noteOut[2][index2];
				index2++;
			}
			tempOut[0][index2]=note;
			tempOut[1][index2]=vel;
			tempOut[2][index2]=onset;
			while (index2<tempOut[2].length-1)
			{
				tempOut[0][index2+1]=Main.noteOut[0][index2];
				tempOut[1][index2+1]=Main.noteOut[1][index2];
				tempOut[2][index2+1]=Main.noteOut[2][index2];
				index2++;
			}
			Main.noteOut=tempOut;
		}
//		for (int i=0;i<Main.noteOut[0].length;i++) {
//			System.out.println("--to-be---generated note:" + Main.noteOut[0][i] + " " + Main.noteOut[1][i] + " " + Main.noteOut[2][i]);
//		}

	}
	public static void waitSym(double wait) // wait in milliseconds
	{
		long waitMS = (long)(wait*60000/(Main.bpm*48));
		try {
			Thread.sleep(waitMS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
